-
Notifications
You must be signed in to change notification settings - Fork 585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for dotnet local tools #2399
Add support for dotnet local tools #2399
Conversation
There are a lot of package download failures in the failing Azure build. |
@SteveGilham Thanks for this. Interesting approach. However, I have some minor issues with it:
I'm not sure how to fix the issues. From a "low" level API perspective we could easily create a helper similar to From an "high" level API perspective (for example
Some other questions are:
What do you think? |
This proposal is the "simplest thing that could possibly work" for this period of transition from the old .net Framework world to the new .net core one -- with the tool helper types all still in the old world where just an The goals were
I dismissed the idea of explicitly injecting just a process runner function (opaquely take command and arguments, and do the launching), as that wouldn't tell the tool helper whether it should do a In the existing ReportGenerator helper, there's not even a test to see if the ReportGenerator.exe exists, let alone a fallback download of the tool as a NuGet package, so an equivalent on the .net core side just for local tools (but not global or original A In the case where the desired |
Unfortunately, I don't understand some parts of your response. Please let me know if I got something wrong. Regarding your goals, I generally agree, but I think a dependency on
I think only the Tool helper knows how the process has to be started (ie if
??
As far as I understand this paragraph this matches my suggestion with creating a functionality similar to
Indeed we could track the docs in a separate issue but with global and local tools we should have some idea how the API should look like, because I don't want to introduce breaking changes later or different looking and behaving APIs across all helpers...
Yes but my point is that fake should handle that internally when you use the |
Yes, the ideal would be to have a
in form, with the body calling into code shared with (newly factored out of) Consuming code in the tool helper would look like
With the current proposed API, the buildOptions function would look like
If instead the API allowed a user supplied
where
simply to make the working directory consistent throughout. The bit that's still TBD as far as I can see would be handling the actual launch -- the |
Of course the related tests are all red at this point.
I think it needs to be let withDotNetTool (packageName:string) (exeName:string) (buildOptions: DotNet.Options -> DotNet.Options) (c:CreateProcess<_>) =
// magic happens here Also considering this issue the signature of Additionally, given that most tools will have the let witFrameworkOrDotNetTool (type:ToolType) (packageName:string) (exeName:string) (buildOptions: DotNet.Options -> DotNet.Options) (c:CreateProcess<_>) =
// magic happens here |
type DotNetTool = | ||
{ | ||
DotNetCli : string option | ||
Tool : string option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add some docs what this "Tool" string means and what "None" means?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do in next update, when I've got something working for withDotNetTool
that I'm happy with.
/// Select which style of tool implementation | ||
type ToolType = | ||
| DotNet of DotNetTool | ||
| Global |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean "Global Tool" or something else? If yes, should we rename "DotNetTool" to "DotNetLocalTool"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Saying DotNet
here covers anything initiated by dotnet toolname
, be it a .net core 3.0 local tool or a pre-3.0 DotNetCliToolReference
tool.
Please merge release/next to get a green build |
In the API I've used tool name rather than package name because they often aren't the same e.g.
|
I have a commit on top of this that applies the change to Fake.DotNet.Paket, for some reason I can't PR onto your branch @SteveGilham but here it is: https://github.com/Tarmil/FAKE/tree/issue-2398 |
@Tarmil I've merged the change into this PR for you. |
Not sure what's up with the Azure build; it looks like it managed to lose the ProjectReference dependency that the other CI servers were happy with. |
The Azure Build is the only one building the legacy fake 4 package which is a separate pre sdk project file. |
To clarify: For the old package it is only important to stay "releasable", there is no need to port the features. But most likely just adding the new files is easier to add the required |
|
||
/// Some extensions for the `CreateProcess` module, opened automatically (use add `open Fake.Core`) | ||
[<AutoOpen>] | ||
module CreateProcessDotNetExt = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: Not a huge fan of AutoOpen (see guidelines). Will try to suggest something else, just wanted to let you know early.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just following the precedent of the definition of withFramework
here, for sake of consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes but first it is part of the Fake.Core.Process
module and second it doesn't contain "new" types and other stuff, maybe we can at least move that outside of the "AutoOpen". Let me take a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving to an explicit module Fake,DotNet.Create Process
would be little hardship, if that's more in line with the current style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that is my current thinking it if could just look like:
Command.RawCommand("localtool", Arguments.OfArgs ["arg1"; "arg2"])
|> CreateProcess.fromCommand
// I feel the name is a bit too long but to get the idea
|> DotNetCreateProcess.with buildOptions // prepare to execute dotnet localtool.
|> Proc.run
|> ignore
Also from a design perspective, I'm not sure why we need to extend the Proc
module because you can always just edit the CreateProcess
instance?
Like I said I will play around with the code now (These are my current thinkings, please feel free to add yours or (dis)agree).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing I'm thinking about is that withDotNetTool
is basically just prefixing everything with "dotnet.exe", I'm not sure if that is what you usually want because usually I feel like you want to replace the first argument as well when using the function (ie when the tool has a different name to the exe file)?
@@ -0,0 +1,121 @@ | |||
namespace Fake.Core |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we mode this to Fake.DotNet (might solve the AutoOpen issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, for consistency with the other CreateProcess
extension, so they all look like they're part of the base module.
-- rather than make them look like parts of Proc/CreateProcess
We seem to have crossed in the middle here (I didn't check for updates to the conversation before committing the changes). In the one remaining contentious bit, the usage I see is like this
where the tool helper supplies some defaults -- a path for framework implementations and a "most likely" name for .net core tools, and allows the user to override. In most cases, "most likely" will be the one name used both for global and CLI tool variants -- awkward cases where the names differ will just have to document what the particular choice of "most likely" is. |
…hFramework' (not working yet)
Steve gilham develop/issue 2398
See SteveGilham#1 I tried several changes (I don't think they are runnable just yet, but ready for some discussions:
|
Working on this was good to get an idea on why you choose some routes. I guess I need a break and will continue later today or tomorrow as there are still some open issues in my proposal. |
As this change is becoming a significant re-architecting, especially compared with the initial minimal impact proposal, I'll step back for the moment, and just merge updates to the PR as they arrive. |
I hope it is not, the idea is to adapt the current architecture to support this use-case (which it should).
But I understand your concerns, just thought it would good to have a second set of eyes to take a look (for example if all use-cases are still possible and the APIs are reasonable). In this case I'll just push to your branch directly, if you have left the corresponsing checkbox active :) |
I've not explicitly checked or unchecked anything, but I'll look out for messages just in case. |
The current implementation should now work. It can be combined with an existing let install = lazy DotNet.install //
let cp =
rawCreateProcess (fun p ->
{ p with
ToolType = ToolType.CreateLocalTool(install.Value) }) We still need to go through all tools and add the parameter (ie replace Now we should take a close look at all the new APIs and check if the naming is OK, which I doubt (and if we should add docs). |
|> CreateProcess.withFrameworkOrDotNetTool parameters.ToolType | ||
|> CreateProcess.withWorkingDirectory parameters.WorkingDir | ||
|> CreateProcess.ensureExitCode | ||
|> fun command -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this was deliberate here, removing the pre-existing trace behaviour
|> fun command ->
Trace.trace command.CommandLine
command
The remaining references to
A brief search hasn't turned up netstandard based versions of any of these tools aside from the .net core SDK 3.0 version of fsc.exe as a self-contained executable; paket and ReportGenerator have been on the bleeding edge by comparison. |
Thanks for taking a look. I think I'll also update the installation docs to recommend the new local tool installation option (maybe even as preferred variant?). Which basically completes "initial dotnet sdk local tool support" from a fake standpoint |
There's nothing in the API naming that looks obviously wrong or out of place to me in the ToolType-related APIs; I've not looked deeply into the re-workings of the CreateProcess internals, for any new public surface. |
Description
Generally as described there, extended to allow specifying the path to dotnet.exe explicitly
TODO
help/markdown
) -- holding off on this until the shape of the change is agreed.